<template>
	<div>
		<el-tabs v-model="state.activeTab" @tab-change="tabChange">
			<el-tab-pane name="tab1" label="待办任务">
				<el-table :data="state.dataList" stripe style="width: 100%" v-loading="state.listLoading">
					<el-table-column prop="approveNo" header-align="center" align="center" label="审批编码"/>
					<el-table-column prop="processDefName" header-align="center" align="center" label="流程名称"/>
					<el-table-column prop="briefReport" header-align="center" align="center" label="流程摘要"/>
					<el-table-column prop="taskName" header-align="center" align="center" label="节点名称"/>
					<el-table-column prop="startTime" header-align="center" align="center" label="开始时间" :formatter="formatDateTime"/>
					<el-table-column prop="startUserName" header-align="center" align="center" label="发起人"/>
					<el-table-column fixed="right" header-align="center" align="center" width="250" label="操作">
						<template #default="scope">
							<el-button type="primary" link v-if="scope.row.assignee != null" @click="processTask(scope.row)">处理</el-button>
							<el-button type="primary" link v-if="scope.row.assignee != null" @click="claimHandle(scope.row, '0')">放弃处理</el-button>
							<el-button type="primary" link v-if="scope.row.assignee == null" @click="claimHandle(scope.row, '1')">签收</el-button>
							<el-button type="primary" link @click="detail(scope.row)" >详情</el-button>
							<el-button type="primary" link @click="trace(scope.row)" >跟踪</el-button>
						</template>
					</el-table-column>
				</el-table>
				<el-pagination
						@size-change="onHandleSizeChange"
						@current-change="onHandleCurrentChange"
						:pager-count="5"
						:page-sizes="[10, 50, 200]"
						v-model:current-page="state.pageParam.page"
						background
						v-model:page-size="state.pageParam.pageSize"
						layout="total, sizes, prev, pager, next, jumper"
						:total="state.total" small>
				</el-pagination>
			</el-tab-pane>
			<el-tab-pane name="tab2" label="我发起">
				<el-table :data="state.dataCreateList" stripe style="width: 100%" v-loading="state.listLoading">
					<el-table-column prop="approveNo" header-align="center" align="center" label="审批编码"/>
					<el-table-column prop="processDefName" header-align="center" align="center" label="流程名称"/>
					<el-table-column prop="briefReport" header-align="center" align="center" label="流程摘要"/>
					<el-table-column prop="taskName" header-align="center" align="center" label="当前节点"/>
					<el-table-column header-align="center" align="center" prop="assigneeName" label="当前处理人"/>
					<el-table-column prop="startTime" header-align="center" align="center" label="开始时间" :formatter="formatDateTime"/>
					<el-table-column fixed="right" header-align="center" align="center" width="250" label="操作">
						<template #default="scope">
							<el-button type="primary" link v-if="scope.row.processState == 'ACTIVE'" @click="recallTaskByStarter(scope.row)">撤回</el-button>
							<el-button type="primary" link @click="detail(scope.row)" >详情</el-button>
							<el-button type="primary" link @click="trace(scope.row)" >跟踪</el-button>
						</template>
					</el-table-column>
				</el-table>
				<el-pagination
						@size-change="onHandleSizeChange"
						@current-change="onHandleCurrentChange"
						:pager-count="5"
						:page-sizes="[10, 50, 200]"
						v-model:current-page="state.pageCreateParam.page"
						background
						v-model:page-size="state.pageCreateParam.pageSize"
						layout="total, sizes, prev, pager, next, jumper"
						:total="state.createTotal" small>
				</el-pagination>
			</el-tab-pane>
			<el-tab-pane name="tab3" label="我参与">
				<el-table :data="state.dataPartakeList" stripe style="width: 100%" v-loading="state.listLoading">
					<el-table-column prop="approveNo" header-align="center" align="center" label="审批编码"/>
					<el-table-column prop="processDefName" header-align="center" align="center" label="流程名称"/>
					<el-table-column prop="briefReport" header-align="center" align="center" label="流程摘要"/>
					<el-table-column prop="taskName" header-align="center" align="center" label="当前节点"/>
					<el-table-column header-align="center" align="center" prop="assigneeName" label="当前处理人"/>
					<el-table-column prop="startTime" header-align="center" align="center" label="开始时间" :formatter="formatDateTime"/>
					<el-table-column prop="startUserName" header-align="center" align="center" label="发起人"/>
					<el-table-column fixed="right" header-align="center" align="center" width="250" label="操作">
						<template #default="scope">
							<el-button type="primary" link v-if="scope.row.processState == 'ACTIVE'" @click="recallTaskAny(scope.row)">撤回</el-button>
							<el-button type="primary" link @click="detail(scope.row)" >详情</el-button>
							<el-button type="primary" link @click="trace(scope.row)" >跟踪</el-button>
						</template>
					</el-table-column>
				</el-table>
				<el-pagination
						@size-change="onHandleSizeChange"
						@current-change="onHandleCurrentChange"
						:pager-count="5"
						:page-sizes="[10, 50, 200]"
						v-model:current-page="state.pagePartakeParam.page"
						background
						v-model:page-size="state.pagePartakeParam.pageSize"
						layout="total, sizes, prev, pager, next, jumper"
						:total="state.partakeTotal" small>
				</el-pagination>
			</el-tab-pane>
		</el-tabs>
		<detailProcessCommon ref="detailRef" @refreshDataList="loadList"></detailProcessCommon>
		<approveProcessCommon ref="approveRef" @refreshDataList="loadList"></approveProcessCommon>
		<undefProcessApprove ref="undefProcessApproveRef" @refreshDataList="loadList" />
		<component :is="state.componentIdApp" ref="customProcessApproveRef" :taskId="state.selectTask.taskId" 
			:processId="state.selectTask.processId" :businessKey="state.selectTask.businessKey"
			 @refreshDataList="loadList" ></component>
		<el-dialog title="流程跟踪" v-model="state.processStateview" width="95%" style="height:600px" destroy-on-close>
			<processStateViewer :processId="state.selectTask.processId"></processStateViewer>
		</el-dialog>
		<el-dialog title="选择撤回节点" v-model="state.recallView">
			<el-form :model="state.recallDataForm" rules="recallDataFormRule" ref="recallDataFormRef">
				<el-form-item label="撤回节点" v-show="state.recallTaskList.length > 1" prop="taskId">
				<el-select v-model="state.recallDataForm.taskKey" placeholder="请选择要撤回的节点">
					<el-option v-for="item in state.recallTaskList" :key="item.taskKey" :label="item.taskName" :value="item.taskKey"></el-option>
				</el-select>
				</el-form-item>
				<el-form-item label="撤回原因" prop="recallReason">
					<el-input v-model="state.recallDataForm.recallReason" placeholder="请输入撤回原因"></el-input>
				</el-form-item>
			</el-form>
			<span slot="footer" class="dialog-footer">
				<el-button type="primary" @click="submitRecall">确定</el-button>
				<el-button type="primary" @click="state.recallView =false">关闭</el-button>
			</span>
		</el-dialog>
	</div>
</template>
<script setup lang="ts" name="todoHome">
import { ElLoading, ElMessage, ElMessageBox, FormInstance } from 'element-plus'
import { defineAsyncComponent, onMounted, reactive, ref } from 'vue'
import { formatDateTime } from '/@/utils/formatTime'
import { TaskVo, workflowApi } from '/@/api/sys/workflow-api'
import { RouteRecordRaw, useRouter } from 'vue-router'

const approveProcessCommon = defineAsyncComponent(() => import('./approveProcessCommon.vue'))
const undefProcessApprove = defineAsyncComponent(() => import('./undefProcessApprove.vue'))
const detailProcessCommon = defineAsyncComponent(() => import('./detailProcessCommon.vue'))
const processStateViewer = defineAsyncComponent(() => import('./processStateViewer.vue'))

const approveRef = ref()
const detailRef = ref()
const undefProcessApproveRef = ref()
const customProcessApproveRef = ref()
const undefProcessDetailRef = ref()
const recallDataFormRef = ref<FormInstance>()

// const router = useRouter()
const state = reactive({
	listLoading: false,
	processStateview: false,
	total: 0,
	dataList: [],
	componentIdApp: null,
	dataListSelections: [],
	dataDictionaryList: {} as any,
	pageParam: {
		page: 1,
		pageSize: 10,
		param: {
		}
	},
	activeTab: ref('tab1'),
	createTotal: 0,
	dataCreateList: [],
	pageCreateParam: {
		page: 1,
		pageSize: 10,
		param: {
		}
	},
	partakeTotal: 0,
	dataPartakeList: [],
	pagePartakeParam: {
		page: 1,
		pageSize: 10,
		param: {
		}
	},
	selectTask: {
		taskId: '',
		processId: '',
		businessKey: '',
	},
	recallDataForm: {
		processId: '',
		taskKey: '',
		recallReason: ''
	},
	recallDataFormRule: {
		recallReason: {required: true, message: '撤回原因不能为空', trigger: 'blur'}
	},
	recallTaskList: [] as TaskVo[],
	recallView: false,
})

const loadList = () => {
	state.listLoading = true
	workflowApi.getTodoTaskListPage(state.pageParam).then(data => {
		if (data && data.code === 0) {
				state.dataList = data.data.records
				state.total = data.data.totalRow
		} else {
				state.dataList = []
				state.total = 0
		}
	}).catch(() => {
	}).finally(() => {
		state.listLoading = false
	})
}

const loadCreateList = () => {
	state.listLoading = true
	workflowApi.getCreateListPage(state.pageCreateParam).then(data => {
		if (data && data.code === 0) {
				state.dataCreateList = data.data.records
				state.createTotal = data.data.totalRow
		} else {
				state.dataCreateList = []
				state.createTotal = 0
		}
	}).catch(() => {
	}).finally(() => {
		state.listLoading = false
	})
}

const loadPartakeList = () => {
	state.listLoading = true
	workflowApi.getPartakeListPage(state.pagePartakeParam).then(data => {
		if (data && data.code === 0) {
				state.dataPartakeList = data.data.records
				state.partakeTotal = data.data.totalRow
		} else {
				state.dataPartakeList = []
				state.partakeTotal = 0
		}
	}).catch(() => {
	}).finally(() => {
		state.listLoading = false
	})
}

// 页面加载时
onMounted(() => {
    // 列表查询
    loadList()
})
// 分页改变
const onHandleSizeChange = (val: number) => {
	if(state.activeTab == 'tab2'){
		state.pageCreateParam.pageSize = val
		loadCreateList()
	}else if(state.activeTab == 'tab3'){
		state.pagePartakeParam.pageSize = val
		loadPartakeList()
	}else{
		state.pageParam.pageSize = val
		loadList()
	}
}
// 分页改变
const onHandleCurrentChange = (val: number) => {
	if(state.activeTab == 'tab2'){
		state.pageCreateParam.pageSize = val
		loadCreateList()
	}else if(state.activeTab == 'tab3'){
		state.pagePartakeParam.pageSize = val
		loadPartakeList()
	}else{
		state.pageParam.pageSize = val
		loadList()
	}
}

/**
 * 待办处理（审批）
 * @param row 
 */
const processTask = (row: any) => {
	if (row.businessDesignerId !== '') {
		//如果流程变量中有businessDesignerId说明是通过通用业务设计的应用，直接跳转通用业务处理界面
		approveRef.value.openDialog(row.processInstanceId, row.taskId, row.businessKey, row.businessDesignerId,
			row.businessDesignerCode)
	}else{
		//其他情况如果定义了审批页
		if (row.formRefKey && row.formRefKey.trim() !== '') {
			state.selectTask.taskId = row.taskId
			state.selectTask.processId = row.processInstanceId
			state.selectTask.businessKey = row.businessKey
			state.componentIdApp = defineAsyncComponent(() => import(/* @vite-ignore */'/@/views/' + row.formRefKey + '.vue'))
			customProcessApproveRef.value.openDialog()
		}else{
			//其他情况如果没定义审批页，走工作流自定义表单的页面
			undefProcessApproveRef.value.openDialog(row.processInstanceId, row.taskId, row.businessKey, row.businessDesignerId, row.businessDesignerCode)
		}
	}
}

const claimHandle = (row: any, sign: string) => {
	state.listLoading = true
	workflowApi.doClaimTask(row.taskId, sign).then(data => {
		if (data && data.code === 0) {
			ElMessage.success('删除成功')
		} else {
				ElMessage.error(data.message)
		}
	}).catch(() => {
		ElMessage.error('处理失败')
	}).finally(() => {
		state.listLoading = false
		loadList()
	})
}

const detail = (row: any) => {
	if (row.businessDesignerId !== '') {
		//如果流程变量中有businessDesignerId说明是通过通用业务设计的应用，直接跳转通用业务详情界面
		detailRef.value.openDialog(row.processInstanceId, row.taskId, row.businessKey, row.businessDesignerId,
			row.businessDesignerCode)
	}else{
		//其他情况如果定义了详情页
		if (row.detailPage && row.detailPage.trim() !== '') {
			state.selectTask.taskId = row.taskId
			state.selectTask.processId = row.processInstanceId
			state.selectTask.businessKey = row.businessKey
			state.componentIdApp = defineAsyncComponent(() => import(/* @vite-ignore */'/@/views/' + row.detailPage + '.vue'))
			customProcessApproveRef.value.openDialog()
		}else{
			//其他情况如果没定义详情页，走工作流自定义表单的页面
			undefProcessDetailRef.value.openDialog()
		}
	}
}
//流程图
const trace = (row: any) => {
	state.selectTask.taskId = row.taskId
	state.selectTask.processId = row.processInstanceId
	state.selectTask.businessKey = row.businessKey
	state.processStateview = true
}

const tabChange = (name: string) => {
	if(name == 'tab2'){
		loadCreateList()
	}else if(name == 'tab3'){
		loadPartakeList()
	}else{
		loadList()
	}
}
//发起人撤回流程，撤回之首节点
const recallTaskByStarter = (row: any) => {
	ElMessageBox.confirm('是否确定撤回流程', '提示', {
		confirmButtonText: '确定',
		cancelButtonText: '取消',
	}).then(() => {
		const loading = ElLoading.service({
			lock: true,
			text: '处理中',
			background: 'rgba(0, 0, 0, 0.7)',
		})
		workflowApi.recallTaskByStarter(row.processInstanceId).then((data) => {
			if (data && data.code === 0) {
				ElMessage.success('撤回成功！')
				loadCreateList()
			} else {
				ElMessage.error(data.message)
			}
		}).catch(() => {
			ElMessage.error('撤回失败！')
		}).finally(() => {
			loading.close()
		})
	})
}
//任意撤回
const recallTaskAny = (row: any) => {
	workflowApi.getCanRecallTask(row.processInstanceId).then((data) => {
		if (data && data.code === 0) {
			if(data.data.length < 1){
				ElMessage.error('没有可撤回的节点！')
			}else{
				state.recallTaskList = data.data
				state.recallView = true
			}
		}else{
			ElMessage.error(data.message)
		}
	}).catch(() => {
		ElMessage.error('撤回失败！')
	})
}
//撤回提交
const submitRecall = (formEl: FormInstance | undefined) => {
	if (!formEl) return
	formEl.validate((valid: boolean) => {
		if (valid) {
			// 提交数据
			const loading = ElLoading.service({
				lock: true,
				text: '处理中',
				background: 'rgba(0, 0, 0, 0.7)',
			})
			if(state.recallTaskList.length == 1) {
				state.recallDataForm.taskKey = state.recallTaskList[0].taskKey
			}
			//调用接口撤回
			workflowApi.recallTaskAny(state.recallDataForm).then((data) => {
				if (data && data.code === 0) {
					ElMessage.success('撤回流程成功')
				}else{
					ElMessage.error(data.message)
				}
			}).catch(() => {
				ElMessage.error('撤回失败！')
			})
		}
	})
}
</script>
